package functionalInterface;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class Demo {

    //函数式接口实例的创建有三种方式：1、lambda表达式；2、方法引用；3、构造方法引用。
    public static void main(String[] args) {
        //1、lambda表达式
        FunctionalInterfaceTest functionalInterfaceTest = string-> {
            System.out.println(string);
        };
        functionalInterfaceTest.say("1 : Hello");

        //2、方法引用
        FunctionalInterfaceTest functionalInterfaceTest2 = Demo::sayHello;
        functionalInterfaceTest2.say("2 : Hello");

        /**
         * 3、构造方法引用
         * 构造函数的结构：接收输入参数，然后返回一个对象。这种约束跟函数式接口的约束很像。
         * 所以只要“输入参数类型”与“输出参数类型”跟FunctionInterfaceTest中的方法约束相同，
         * 就可以创建出FunctionInterfaceTest接口的实例，如下，String的构造方法中有
         * new String(str)的构造方法，所以可以得到实例。
         * 这里存在一个类型推断的问题，JDK的编译器已经帮我们自动找到了只有一个参数，且是String类型的构造方法。
         * 这就是我们直接String::new，没有指定使用哪一个构造方法，却可以创建实例的原因
        **/
        FunctionalInterfaceTest5 functionalInterfaceTest5 = String::new;
        System.out.println(functionalInterfaceTest5.say("5 : Hello"));



        //Function<T,R> 接收一个T类型的参数，返回一个R类型的结果
        Function<String,String> function = item -> item +"返回值";

        //Consumer<T>   接收一个T类型的参数，不返回值
        Consumer<String> consumer = item -> {System.out.println(item);};//lambda语句，使用大括号，没有return关键字，表示没有返回值

        //Predicate<T>  接收一个T类型的参数，返回一个boolean类型的结果
        Predicate<String> predicate = item -> "".equals(item);

        // Supplier<T>  不接受参数，返回一个T类型的结果
        Supplier<String> supplier = () -> new String("");

        List<String> list = Arrays.asList("A","B","C","D","E");
        list.stream()
                .map(v -> v.toLowerCase())          //传入的是一个Function函数式接口//
                .filter(v -> "abc".contains(v))     //传入的是一个Predicate函数式接口
                .forEach(v->{                       //传入的是一个Consumer函数式接口
                    System.out.println(v);
                });
    }


    public static void sayHello(String string){
        System.out.println(string);
    }
}
